#ifndef GD32_RCU_H
#define GD32_RCU_H
#include "gd32f3x0.h"

#define R_RCU_BASE 0x40021000

struct regRCU_CTL0 {       // Reset value: 0x0000 XX83
    uint16_t IRC8MEN: 1;  // Internal High Speed oscillator Enable
    uint16_t IRC8MSTB: 1; // IRC8M High Speed Internal Oscillator stabilization Flag
    uint16_t : 1;
    uint16_t IRC8MADJ: 5;   // High Speed Internal Oscillator clock trim adjust value.These bits are set by software
    uint16_t IRC8MCALIB: 8; // High Speed Internal Oscillator calibration value register

    uint16_t HXTALEN: 1;  // External High Speed oscillator Enable
    uint16_t HXTALSTB: 1; // External crystal oscillator (HXTAL) clock stabilization flag
    uint16_t HXTALBPS: 1; // External crystal oscillator (HXTAL) clock bypass mode enable
    uint16_t CKMEN: 1;    // HXTAL Clock Monitor Enable
    uint16_t : 4;
    uint16_t PLLEN: 1;  // PLL enable
    uint16_t PLLSTB: 1; // PLL Clock Stabilization Flag
    uint16_t : 6;
};
#define R_RCU_CTL0 ((struct regRCU_CTL0 *) (R_RCU_BASE + 0x00))

enum AHBPSC_Alternative {
    AHB_Prescaler_1 = 0b000U,
    AHB_Prescaler_2 = 0b1000U,
    AHB_Prescaler_4 = 0b1001U,
    AHB_Prescaler_8 = 0b1010U,
    AHB_Prescaler_16 = 0b1011U,
    AHB_Prescaler_64 = 0b1100U,
    AHB_Prescaler_128 = 0b1101U,
    AHB_Prescaler_256 = 0b1110U,
    AHB_Prescaler_512 = 0b1111U
};

enum APBxPSC_Alternative {
    APBx_Prescaler_1 = 0b000U,
    APBx_Prescaler_2 = 0b100U,
    APBx_Prescaler_4 = 0b101U,
    APBx_Prescaler_8 = 0b110U,
    APBx_Prescaler_16 = 0b111U,
};

enum ADCPSC_Alternative {
    ADC_Prescaler_2 = 0b000U,
    ADC_Prescaler_4 = 0b001U,
    ADC_Prescaler_6 = 0b010U,
    ADC_Prescaler_8 = 0b011U,

    ADC_Prescaler_3 = 0b100U,
    ADC_Prescaler_5 = 0b101U,
    ADC_Prescaler_7 = 0b110U,
    ADC_Prescaler_9 = 0b111U,
};

enum USBFSPSC_Alternative {
    USBFS_Prescaler_1dot5 = 0b000U,
    USBFS_Prescaler_1 = 0b001U,
    USBFS_Prescaler_2dot5 = 0b010U,
    USBFS_Prescaler_2 = 0b011U,
    USBFS_Prescaler_3 = 0b100U,
    USBFS_Prescaler_3dot5 = 0b101U // 0b110 0b111 also
};
struct regRCU_CFG0 {      // Reset value: 0x0000 0000
    uint16_t SCS: 2;     // System clock switch
    uint16_t SCSS: 2;    // System clock switch status
    uint16_t AHBPSC: 4;  // AHB 1rescaler selection.Ref.AHBPSC_Alternative
    uint16_t APB1PSC: 3; // APB1 prescaler selection.Ref.APBxPSC_Alternative
    uint16_t APB2PSC: 3; // APB2 prescaler selection.Ref.APBxPSC_Alternative
    uint16_t ADCPSC: 2;  // ADCPSC[1:0] ADC clock prescaler selection.Ref.ADCPSC_Alternative.See RCU_CFG2 also.

    uint16_t PLLSEL: 1;   // PLL Clock Source Selection
    uint16_t PLLPREDV: 1; // HXTAL or CK_IRC48M divider for PLL source clock selection This bit is the same bit as bit PREDV[0] from RCU_CFG1
    uint16_t PLLMF: 4;    // PLLMF[3:0] PLL multiply factor and Factor = (reg val)+2.See RCU_CFG1 also.
    uint16_t USBFSPSC: 2; // USBFSPSC[1:0] USBFS clock prescaler selection.Ref.USBFSPSC_Alternative..See RCU_CFG2 also.
    uint16_t CKOUTSEL: 3; // CK_OUT Clock Source Selection.See datasheet
    uint16_t PLLMF_4: 1;  // Bit 4 of PLLMF register
    uint16_t CKOUTDIV: 3; // The CK_OUT divider.The CK_OUT is divided by 2^(reg val).
    uint16_t PLLDV: 1;    // The CK_PLL divide by 1 or 2 for CK_OUT
};
#define R_RCU_CFG0 ((struct regRCU_CFG0 *) (R_RCU_BASE + 0x04))

struct regRCU_INT {           // Reset value: 0x0000 0000
    uint16_t IRC40KSTBIF: 1; // IRC40K stabilization interrupt flag
    uint16_t LXTALSTBIF: 1;  // LXTAL stabilization interrupt flag
    uint16_t IRC8MSTBIF: 1;  // IRC8M stabilization interrupt flag
    uint16_t HXTALSTBIF: 1;  // HXTAL stabilization interrupt flag
    uint16_t PLLSTBIF: 1;    // PLL stabilization interrupt flag
    uint16_t IRC28MSTBIF: 1; // IRC28M stabilization interrupt flag
    uint16_t : 1;
    uint16_t CKMIF: 1; // HXTAL Clock Stuck Interrupt Flag

    uint16_t IRC40KSTBIE: 1; // IRC40K Clock Stuck Interrupt enable
    uint16_t LXTALSTBIE: 1;  // LXTAL Clock Stuck Interrupt enable
    uint16_t IRC8MSTBIE: 1;  // IRC8M Clock Stuck Interrupt enable
    uint16_t HXTALSTBIE: 1;  // HXTAL Clock Stuck Interrupt enable
    uint16_t PLLSTBIE: 1;    // PLL Clock Stuck Interrupt enable
    uint16_t IRC28MSTBIE: 1; // IRC28M Clock Stuck Interrupt enable
    uint16_t : 2;

    uint16_t IRC40KSTBIC: 1; // IRC40K stabilization interrupt clear
    uint16_t LXTALSTBIC: 1;  // LXTAL stabilization interrupt clear
    uint16_t IRC8MSTBIC: 1;  // IRC8M stabilization interrupt clear
    uint16_t HXTALSTBIC: 1;  // HXTAL stabilization interrupt clear
    uint16_t PLLSTBIC: 1;    // PLL stabilization interrupt clear
    uint16_t IRC28MSTBIC: 1; // IRC28M stabilization interrupt clear
    uint16_t : 1;
    uint16_t CKMIC: 1; // HXTAL Clock Stuck Interrupt Clear
    uint16_t : 8;
};
#define R_RCU_INT ((struct regRCU_INT *) (R_RCU_BASE + 0x08))

struct regRCU_APB2RST { // Reset value: 0x0000 0000
    uint16_t CFG_CMP_RST: 1;
    uint16_t : 8;
    uint16_t ADC_RST: 1;
    uint16_t : 1;
    uint16_t TIM0_RST: 1;
    uint16_t SPI0_RST: 1;
    uint16_t : 1;
    uint16_t UART0_RST: 1;
    uint16_t : 1;

    uint16_t TIM14_RST: 1;
    uint16_t TIM15_RST: 1;
    uint16_t TIM16_RST: 1;
    uint16_t : 13;
};
#define R_RCU_APB2RST ((struct regRCU_APB2RST *) (R_RCU_BASE + 0x0C))

struct regRCU_APB1RST { // Reset value: 0x0000 0000
    uint16_t TIM1_RST: 1;
    uint16_t TIM2_RST: 1;
    uint16_t : 2;
    uint16_t TIM5_RST: 1;
    uint16_t : 3;

    uint16_t TIM13_RST: 1;
    uint16_t : 2;
    uint16_t WWDGT_RST: 1;
    uint16_t : 2;
    uint16_t SPI1_RST: 1;
    uint16_t : 1;

    uint16_t : 1;
    uint16_t UART1_RST: 1;
    uint16_t : 3;
    uint16_t I2C0_RST: 1;
    uint16_t I2C1_RST: 1;
    uint16_t : 5;
    uint16_t PMU_RST: 1;
    uint16_t DAC_RST: 1;
    uint16_t CEC_RST: 1;
    uint16_t : 1;
};
#define R_RCU_APB1RST ((struct regRCU_APB1RST *) (R_RCU_BASE + 0x10))

struct regRCU_AHBEN { // Reset value: 0x0000 0014
    uint16_t DMA_EN: 1;
    uint16_t : 1;
    uint16_t SRAMSP_EN: 1;
    uint16_t : 1;
    uint16_t FMCSP_EN: 1;
    uint16_t : 1;
    uint16_t CRC_EN: 1;
    uint16_t : 5;
    uint16_t USBFS_EN: 1;
    uint16_t : 3;

    uint16_t : 1;
    uint16_t PA_EN: 1;
    uint16_t PB_EN: 1;
    uint16_t PC_EN: 1;
    uint16_t PD_EN: 1;
    uint16_t : 1;
    uint16_t PF_EN: 1;
    uint16_t : 1;
    uint16_t TSI_EN: 1;
    uint16_t : 7;
};
#define R_RCU_AHBEN ((struct regRCU_AHBEN *) (R_RCU_BASE + 0x14))

struct regRCU_APB2EN { // Reset value: 0x0000 0000
    uint16_t CFG_CMP_EN: 1;
    uint16_t : 8;
    uint16_t ADC_EN: 1;
    uint16_t : 1;
    uint16_t TIM0_EN: 1;
    uint16_t SPI0_EN: 1;
    uint16_t : 1;
    uint16_t UART0_EN: 1;
    uint16_t : 1;

    uint16_t TIM14_EN: 1;
    uint16_t TIM15_EN: 1;
    uint16_t TIM16_EN: 1;
    uint16_t : 13;
};
#define R_RCU_APB2EN ((struct regRCU_APB2EN *) (R_RCU_BASE + 0x18))

struct regRCU_APB1EN { // Reset value: 0x0000 0000
    uint16_t TIM1_EN: 1;
    uint16_t TIM2_EN: 1;
    uint16_t : 2;
    uint16_t TIM5_EN: 1;
    uint16_t : 3;

    uint16_t TIM13_EN: 1;
    uint16_t : 2;
    uint16_t WWDGT_EN: 1;
    uint16_t : 2;
    uint16_t SPI1_EN: 1;
    uint16_t : 1;

    uint16_t : 1;
    uint16_t UART1_EN: 1;
    uint16_t : 3;
    uint16_t I2C0_EN: 1;
    uint16_t I2C1_EN: 1;
    uint16_t : 5;
    uint16_t PMU_EN: 1;
    uint16_t DAC_EN: 1;
    uint16_t CEC_EN: 1;
    uint16_t : 1;
};
#define R_RCU_APB1EN ((struct regRCU_APB1EN *) (R_RCU_BASE + 0x1C))

struct regRCU_BDCTL { // Reset value: 0x0000 0018
    uint16_t LXTAL_EN: 1;
    uint16_t LXTAL_STB: 1;
    uint16_t LXTAL_BPS: 1;
    uint16_t LXTAL_DRI: 2; // LXTAL drive capability/intensity
    uint16_t : 3;
    uint16_t RTCSRC: 2; // RTC clock entry selection
    uint16_t : 5;
    uint16_t RTC_EN: 1;

    uint16_t BKP_RST: 1;
    uint16_t : 15;
};
#define R_RCU_BDCTL ((struct regRCU_BDCTL *) (R_RCU_BASE + 0x20))

struct regRCU_RSTSCK { // Reset value: 0x0C00 0000, reset flags reset by power Reset only
    uint16_t IRC40K_EN: 1;
    uint16_t IRC40K_STB: 1;
    uint16_t : 14;
    uint16_t : 7;
    uint16_t V12_RSTF: 1;
    uint16_t RSTFC: 1;
    uint16_t OBL_RSTF: 1;
    uint16_t EP_RSTF: 1;
    uint16_t POR_RSTF: 1;
    uint16_t SW_RSTF: 1;
    uint16_t FWDGT_RSTF: 1;
    uint16_t WWDGT_RSTF: 1;
    uint16_t LPDGT_RSTF: 1;
};
#define R_RCU_RSTSCK ((struct regRCU_RSTSCK *) (R_RCU_BASE + 0x24))

struct regRCU_AHBRST { // Reset value: 0x0000 0000
    uint16_t : 12;
    uint16_t USBFS_RST: 1;
    uint16_t : 3;

    uint16_t : 1;
    uint16_t PA_RST: 1;
    uint16_t PB_RST: 1;
    uint16_t PC_RST: 1;
    uint16_t PD_RST: 1;
    uint16_t : 1;
    uint16_t PF_RST: 1;
    uint16_t : 1;
    uint16_t TSI_RST: 1;
    uint16_t : 7;
};
#define R_RCU_AHBRST ((struct regRCU_AHBRST *) (R_RCU_BASE + 0x28))

struct regRCU_CFG1 {    // Reset value: 0x0000 0000
    uint16_t PREDV: 4; // CK_HXTAL or CK_IRC48M divider previous PLL.Divided by (PREDV + 1).
    uint16_t : 12;
    uint16_t : 14;
    uint16_t PLLPRESEL: 1; // PLL clock source preselection
    uint16_t PLLMF_5: 1;     // PLLMF[5] PLL multiply factor and Factor = (reg val)+2.See RCU_CFG0 also.
};
#define R_RCU_CFG1 ((struct regRCU_CFG1 *) (R_RCU_BASE + 0x2C))

struct regRCU_CFG2 {        // Reset value: 0x0000 0000
    uint16_t USART0SEL: 2; // CK_USART0 clock source selection.Ref.datasheet
    uint16_t : 4;
    uint16_t CECSEL: 1; // CK_CEC clock source selection
    uint16_t : 1;
    uint16_t ADCSEL: 1; // CK_ADC clock source selection
    uint16_t : 7;

    uint16_t IRC28MDIV: 1; // IRC28M divider or not
    uint16_t : 13;
    uint16_t USBFSPSC_2: 1; // Bit 2 of USBFSPSC.see bits 23:22 of RCU_CFG0
    uint16_t ADCPSC: 1;   // Bit 2 of ADCPSC.see bits 15:14 of RCU_CFG0
};
#define R_RCU_CFG2 ((struct regRCU_CFG2 *) (R_RCU_BASE + 0x30))

struct regRCU_CTL1 {        // Reset value: 0x0000 XX80
    uint16_t IRC28MEN: 1;  // IRC28M Internal 28M RC oscillator Enable
    uint16_t IRC28MSTB: 1; // IRC28M Internal 28M RC Oscillator stabilization Flag
    uint16_t : 1;
    uint16_t IRC28MADJ: 5;   // Internal 28M RC Oscillator clock trim adjust value
    uint16_t IRC28MCALIB: 8; // Internal 28M RC Oscillator calibration value register
    uint16_t : 16;
};
#define R_RCU_CTL1 ((struct regRCU_CTL1 *) (R_RCU_BASE + 0x34))

struct regRCU_ADDCTL {     // Reset value: 0x8000 0000
    uint16_t CK48MSEL: 1; // 48MHz clock selection
    uint16_t : 15;

    uint16_t IRC48MEN: 1;  // Internal 48MHz RC oscillator enable
    uint16_t IRC48MSTB: 1; // Internal 48MHz RC oscillator clock stabilization Flag    uint16_t : 15;
    uint16_t : 6;
    uint16_t IRC48MCALIB: 8; // Internal 48MHz RC oscillator calibration value register
};
#define R_RCU_ADDCTL ((struct regRCU_ADDCTL *) (R_RCU_BASE + 0xC0))

struct regRCU_ADDINT { // Reset value: 0x0000 0000
    uint16_t : 6;
    uint16_t IRC48MSTBIF: 1; // IRC48M stabilization interrupt flag
    uint16_t : 7;
    uint16_t IRC48MSTBIE: 1; // Internal 48 MHz RC oscillator Stabilization Interrupt Enable
    uint16_t : 1;

    uint16_t : 6;
    uint16_t IRC48MSTBIC: 1; // Internal 48 MHz RC oscillator Stabilization Interrupt Clear
    uint16_t : 9;
};
#define R_RCU_ADDINT ((struct regRCU_ADDINT *) (R_RCU_BASE + 0xCC))

struct regRCU_ADDAPB1EN { // Reset value: 0x0000 0000
    uint32_t : 27;
    uint32_t CTCEN: 1; // CTC clock enable
    uint32_t : 4;
};
#define R_RCU_ADDAPB1EN ((struct regRCU_ADDAPB1EN *) (R_RCU_BASE + 0xF8))

struct regRCU_ADDAPB1RST { // Reset value: 0x0000 0000
    uint32_t : 27;
    uint32_t CTCRST: 1; // CTC reset
    uint32_t : 4;
};
#define R_RCU_ADDAPB1RST ((struct regRCU_ADDAPB1RST *) (R_RCU_BASE + 0xFC))

struct regRCU_VKEY { // Reset value: 0x0000 0000
    uint32_t KEY;    // The key of RCU_DSV register.key=0x1A2B3C4D
};
#define R_RCU_VKEY ((struct regRCU_VKEY *) (R_RCU_BASE + 0x100))

struct regRCU_DSV {      // Reset value: 0x0000 0000
    uint16_t DSLPVS: 2; // Deep-sleep mode voltage select.0b00 : The core voltage is 1.0V in Deep-sleep mode.
    uint16_t : 14;
    uint16_t : 16;
};
#define R_RCU_DSV ((struct regRCU_DSV *) (R_RCU_BASE + 0x134))
#endif // GD32_RCU_H
